package bingo.codeweaver.core.metadata;

import java.lang.reflect.Field;

import net.bingosoft.common.util.StringHelper;
import bingo.codeweaver.core.annotation.Column;
import bingo.codeweaver.core.strategy.DefaultNamingStrategy;
import bingo.codeweaver.core.strategy.NamingStrategy;
import bingo.codeweaver.core.utils.SqlJavaTypeMapping;


/**
 * Mar 6, 2009 6:42:52 AM Column.java
 * Author:yangdongyu(yangdy@bingosoft.net)
 * ReadMe:
 * ChangeLog:
 */
public class ColumnMetadata {

	private String name;
	private String typeName;
	private boolean nullable = true;
	private String defaultValue = "";
	private String comment = "";

	private boolean isPrimaryKey;
	private boolean isForeignKey;
	private int columnSize;
	private int length;
	private int scale;

	private int decimalDigits;

	private int displayOrder;
	private TableMetadata table ;
	private NamingStrategy namingStrategy = new DefaultNamingStrategy();


	public ColumnMetadata() {}
	
	ColumnMetadata(TableMetadata tableMetadata, Field f) {
		this.table = tableMetadata;
		if(f.isAnnotationPresent(Column.class)){
			Column c = f.getAnnotation(Column.class);
			name = StringHelper.isEmpty(c.name()) ? namingStrategy.toColumnName(f.getName()) : c.name();
			typeName = StringHelper.isEmpty(c.dataType()) ? getSQLType(f,c) : c.dataType();
			nullable = c.nullable();
			defaultValue = c.defaultValue();
			comment = c.comment();
			isPrimaryKey = c.primaryKey();
			if(isPrimaryKey){
				nullable = false;
			}
		}else{
			name = namingStrategy.toColumnName(f.getName()) ;
			typeName = getSQLType(f,null);
			nullable = true;
			if(isPrimaryKey){
				nullable = false;
			}
		}
		
	}

	protected String getSQLType(Field f, Column c) {
		if(String.class == f.getType()){
			if(c != null){
				return SqlJavaTypeMapping.getSQLType(f.getType()) + "("+c.length()+")"; 
			}else{
				return SqlJavaTypeMapping.getSQLType(f.getType()) + "(100)";
			}
		}
		return SqlJavaTypeMapping.getSQLType(f.getType());
	}

	public String getMethodName(){
		return getNamingStrategy().toClassName(name);
	}

	public String getPropertyName(){
		return getNamingStrategy().toPropertyName(name);
	}
	public NamingStrategy getNamingStrategy(){
		if(this.table.getNamingStrategy() != null){
			return this.table.getNamingStrategy();
		}else{
			return this.namingStrategy;
		}

	}

	public int getDecimalDigits() {
		return decimalDigits;
	}
	public void setDecimalDigits(int decimalDigits) {
		this.decimalDigits = decimalDigits;
	}
	public int getDisplayOrder() {
		return displayOrder;
	}
	public void setDisplayOrder(int displayOrder) {
		this.displayOrder = displayOrder;
	}
	public int getLength() {
		return length;
	}
	public void setLength(int length) {
		this.length = length;
	}
	public int getColumnSize() {
		return columnSize;
	}
	public void setColumnSize(int columnSize) {
		this.columnSize = columnSize;
	}
	public boolean isPrimaryKey() {
		return isPrimaryKey;
	}
	public void setPrimaryKey(boolean isPrimaryKey) {
		this.isPrimaryKey = isPrimaryKey;
	}
	public boolean isForeignKey() {
		return isForeignKey;
	}
	public void setForeignKey(boolean isForeignKey) {
		this.isForeignKey = isForeignKey;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getTypeName() {
		return typeName;
	}
	public void setTypeName(String typeName) {
		this.typeName = typeName;
	}
	public boolean getNullable() {
		return nullable;
	}
	public void setNullable(boolean nullable) {
		this.nullable = nullable;
	}
	public String getDefaultValue() {
		if("null".equals(defaultValue)){
			return null;
		}
		return defaultValue;
	}
	public void setDefaultValue(String defaultValue) {
		this.defaultValue = defaultValue;
	}
	public String getComment() {
		if("null".equals(comment)) return null;
		return comment;
	}
	public void setComment(String comment) {
		this.comment = comment;
	}
	public TableMetadata getTable() {
		return table;
	}
	public void setTable(TableMetadata table) {
		table.addColumn(this);
		this.table = table;
	}
	public int getScale() {
		return scale;
	}
	public void setScale(int scale) {
		this.scale = scale;
	}

	public String getJavaTypeName(){
		if("NUMBER".equals(typeName) && (scale == 0)){
			return decimalDigits < 10 ? "Integer" : "Long";
		}else{
			return SqlJavaTypeMapping.getJavaType(typeName);
		}
	}

	public String toString(){
		return this.name;
	}
	
	public static void main(String[] args) {
		System.out.println(Integer.toString(Integer.MAX_VALUE, 10).length());
	}

}
